package me.pppploi8.webmcs.main.urlmapping;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.util.Calendar;
import java.util.UUID;

import javax.servlet.http.Cookie;

import org.apache.commons.io.FileUtils;

import me.pppploi8.webmcs.http.jetty.HttpUrlMapping;
import me.pppploi8.webmcs.minecraft.server.core.McServerFactory;


/**
 *
 * @author pppploi8
 */

public class WebmcsLoginSerivce extends HttpUrlMapping{
    private static final char HEX_DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    private File pwdFile;
    private String pwd = null;
    
    public WebmcsLoginSerivce() throws IOException{
        pwdFile =  new File(McServerFactory.getMcServerCore().getServerPath().getParent() + "/password.key");
        if (!pwdFile.exists()) {
            pwdFile.getParentFile().mkdirs();
            pwdFile.createNewFile();
        }
        pwdFile.setWritable(false);
        readPasswordData();
    }
    private void readPasswordData() throws FileNotFoundException, IOException{
        InputStream is = new FileInputStream(pwdFile);
        byte[] bytes = new byte[33];
        if (is.read(bytes)==32)
            pwd = new String(bytes,0,32);
        is.close();
    }
    public Object image() throws IOException{
    	ByteArrayOutputStream os = new ByteArrayOutputStream();
    	String s = VerifyCodeUtils.outputVerifyImage(100, 50, os, 4);
    	getRequest().getSession().setAttribute("verifyCode", s);
    	getResponse().addHeader("Content-Type", "image/bmp");
    	getResponse().getOutputStream().write(os.toByteArray());
    	getResponse().getOutputStream().close();
    	return null;
    }
    /**
     * 返回是否是第一次登陆，如果是则返回true，否则返回false
     * @return 
     */
    public String isfirst(){
        if (pwd==null || pwd.equals(""))
            return "{\"status\":true,\"isfirst\":true}";
        return "{\"status\":true,\"isfirst\":false}";
    }
    /**
     * 登陆系统，要求传递username和password、saveLoginStatus字段
     * @return 返回一个JSON，格式为{"status":{status},"name":"{username}"}
     * @throws IOException 
     */
    public String login() throws IOException{
    	String name = (String)getRequest().getSession().getAttribute("username");
        if (name != null)
        	return "{\"status\":false,\"msg\":\"ALREADYLOGIN\"}";
        String username = getRequest().getParameter("username");
        String password = getRequest().getParameter("password");
        String saveLoginStatus = getRequest().getParameter("saveLoginStatus");
        String code = getRequest().getParameter("code");
        String verifyCode = (String)getRequest().getSession().getAttribute("verifyCode");
        getRequest().getSession().setAttribute("verifyCode", null);//验证码是一次性的
        if (verifyCode == null || code == null || !verifyCode.equals(code.toUpperCase())){
        	return "{\"status\":false,\"msg\":\"CODEERROR\"}";
        }
        if (username==null || password==null || 
            username.equals("") || password.equals("") ||
            !getPwdMd5(username, password).equals(pwd)){
            return "{\"status\":false,\"msg\":\"CHECKERROR\"}";
        }
        getRequest().getSession().setAttribute("username", username);
        if ("true".equals(saveLoginStatus)){
        	// 生成一个随机的UUID保存到文件login.status中
        	String uuid = UUID.randomUUID().toString().replace("-", "");
        	Calendar date = Calendar.getInstance();
        	date.add(Calendar.DATE, 7);
        	FileUtils.writeStringToFile(new File(McServerFactory.getMcServerCore().getServerPath().getParent() + "/login.status"), username + "\r\n" + date.getTimeInMillis() + "\r\n" + uuid, "UTF-8");
        	// 设置Cookie
        	Cookie cookie = new Cookie("uuid", uuid);
        	cookie.setHttpOnly(true);
        	cookie.setMaxAge(7 * 24 * 60 * 60);
        	getResponse().addCookie(cookie);
        }
        return "{\"status\":true}";
    }
    /**
     * 初始化账号数据，要求传递username和password字段
     * @return 返回false或者true
     */
    public String init() throws FileNotFoundException, IOException{
        if (pwd!=null && !pwd.equals(""))
            return "{\"status\":false,\"msg\":\"ALREADYINIT\"}";
        String username = getRequest().getParameter("username");
        String password = getRequest().getParameter("password");
        if (username==null || password==null || username.equals("") || password.equals("")){
            return "{\"status\":false,\"msg\":\"PARAMERROR\"}";
        }
        pwd = getPwdMd5(username, password);
        getRequest().getSession().setAttribute("username", username);
        pwdFile.setWritable(true);
        OutputStream os = new FileOutputStream(pwdFile);
        os.write(pwd.getBytes());
        os.flush();
        os.close();
        pwdFile.setWritable(false);
        return "{\"status\":true}";
    }
    /**
     * 获取用户名，如果未登陆直接返回空
     * @return 
     */
    public String getusername(){
        String name = (String)getRequest().getSession().getAttribute("username");
        if (name == null)
        	return "{\"status\":false,\"msg\":\"NOTLOGIN\"}";
        return "{\"status\":true,\"name\":\""+name+"\"}";
    }
    public void loginout() throws IOException{
        getRequest().getSession().setAttribute("username", null);
        new File(McServerFactory.getMcServerCore().getServerPath().getParent() + "/login.status").delete();
    }
    
    private String toHexString(byte[] b) {
        StringBuilder sb = new StringBuilder(b.length * 2);
        for (int i = 0; i < b.length; i++) {
            sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]);
            sb.append(HEX_DIGITS[b[i] & 0x0f]);
        }
        return sb.toString();
    }
    private String getPwdMd5(String username, String password) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(username.getBytes("UTF-8"));
            String md5_1 = toHexString(digest);
            String s = md5_1 + password;
            return toHexString(md.digest(s.getBytes("UTF-8")));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
